Skip to content

Conversation

@faridnsh
Copy link

@faridnsh faridnsh commented Oct 29, 2025

More context on #75. Closes #75

Basically adds orderBy, first and last parameters to groupedAggregates. orderBy accepts any possible field aggregations. Note that I still don't have a very good understanding of the project, this PR is party AI generated and partly from copy pasting various concepts around, would appreciate deep review from someone who understands the code better to see if there can better ways.

Performance impact

Slight performance impact in startup time due to added(18 entries per numerical fields in AggregatesOrderBy enum)

Security impact

Shouldn't be.

Checklist

  • My code matches the project's code style and yarn lint:fix passes. - I'm working on estlint to run properly
  • I've added tests for the new feature, and yarn test passes.
  • I have detailed the new feature in the relevant documentation.
  • I have added this feature to 'Pending' in the RELEASE_NOTES.md file (if one exists). - File doesn't exist
  • If this is a breaking change I've explained why. - not a breaking change

Copy link
Member

@benjie benjie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really thorough, I like it! I wonder how we avoid type explosion with this - perhaps we should have an opt-in to the feature? I don't think index behaviours can save us here. This plugin already adds a lot of types to the schema 😅

For now let's drop the last argument.

Comment on lines +278 to +282
- `first` / `last` – slice the ordered groups, returning only the leading or
trailing `n` groups.

Always pair `first` or `last` with an explicit `orderBy` so PostgreSQL can
deterministically rank the groups before trimming them.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest that we remove last - if they need that they should do the inverse order.

Comment on lines +337 to +338
When using `last`, be sure to supply an `orderBy` so the database can produce a
deterministic ordering before the tail slice is applied.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should default to ordering by the group by clauses; I didn't realise we didn't do that already.

Comment on lines +20 to +21
orderBy: [SUM_POINTS_ASC]
last: 2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
orderBy: [SUM_POINTS_ASC]
last: 2
orderBy: [SUM_POINTS_ASC]
first: 2

Comment on lines +337 to +339
When using `last`, be sure to supply an `orderBy` so the database can produce a
deterministic ordering before the tail slice is applied.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When using `last`, be sure to supply an `orderBy` so the database can produce a
deterministic ordering before the tail slice is applied.

Comment on lines +46 to +56
exports[`GroupedAggregatesOrderBy: sql 1`] = `
[
"select
(coalesce(sum(__match_stats__."points"), '0'))::text as "0",
__match_stats__."player_id"::text as "1"
from "test"."match_stats" as __match_stats__
group by __match_stats__."player_id"
order by coalesce(sum(__match_stats__."points"), '0') desc
limit 2;",
]
`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 Where's the other query...?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is that when switching to last with reverse ordering, it became the same exact query for the database and it was deduplicated so it was never executed.

Comment on lines +199 to +225
last: {
type: build.graphql.GraphQLInt,
description: build.wrapDescription(
"Only include the last `n` grouped aggregates.",
"arg"
),
applyPlan: EXPORTABLE(
() =>
function (
_$parent,
$pgSelect: PgSelectStep<any>,
arg
) {
const selectAny = $pgSelect as any;
const originalAssert =
selectAny.assertCursorPaginationAllowed;
try {
selectAny.assertCursorPaginationAllowed = () => {};
$pgSelect.setLast(arg.getRaw());
} finally {
selectAny.assertCursorPaginationAllowed =
originalAssert;
}
},
[]
),
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
last: {
type: build.graphql.GraphQLInt,
description: build.wrapDescription(
"Only include the last `n` grouped aggregates.",
"arg"
),
applyPlan: EXPORTABLE(
() =>
function (
_$parent,
$pgSelect: PgSelectStep<any>,
arg
) {
const selectAny = $pgSelect as any;
const originalAssert =
selectAny.assertCursorPaginationAllowed;
try {
selectAny.assertCursorPaginationAllowed = () => {};
$pgSelect.setLast(arg.getRaw());
} finally {
selectAny.assertCursorPaginationAllowed =
originalAssert;
}
},
[]
),
},

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants